<?php
require_once 'Log.php';

/**
 * 底层Model类，提供（单库/分库）数据库常用的增、删、改、查方法
 * 
 * @author wangjiajun,wanggang
 */
class OpModel
{
    const LOG_EMERG   = 0;  // Emergency: system is unusable
    const LOG_ALERT   = 1;  // Alert: action must be taken immediately
    const LOG_CRIT    = 2;  // Critical: critical conditions
    const LOG_ERR     = 3;  // Error: error conditions
    const LOG_WARN    = 4;  // Warning: warning conditions
    const LOG_NOTICE  = 5;  // Notice: normal but significant condition
    const LOG_INFO    = 6;  // Informational: informational messages
    const LOG_DEBUG   = 7;  // Debug: debug messages
    
    protected $_logger;
    private $_errno = 0;
    private $_error = '';
    
    /**
     * 根据类的常量名获取常量值
     * 
     * @param string $constName
     * @param string $startWith 检测常量名的前缀
     * @param mixed $defaultVal 如果没有找到常量默认的返回值
     * @param string $className If PHP 5 >= 5.3.0, use get_called_class()
     * @return mixed
     */
    protected static function _getConstByName($constName, $startWith, $defaultVal, $className)
    {
        $constName = strtoupper($constName);
        if (!empty($startWith) && strpos($constName, $startWith) !== 0) {
            return $defaultVal;
        }
        
        static $consts = NULL;
        if ($consts === NULL) {
            $ref = new ReflectionClass($className);
            $constants = $ref->getConstants();
            $consts = array();
            foreach ($constants as $name => $val) {
                $consts[$name] = $val;
            }
        }
        
        return isset($consts[$constName]) ? $consts[$constName] : $defaultVal;
    }
    
    function __construct($logger = NULL)
    {
        $this->setLogger($logger);
    }
    
    /**
     * 设置日志对象，该对象必须具有如下成员函数：
     * $logger->log($message, $priority)
     * @param $logger
     * @return boolean
     */
    public function setLogger($logger)
    {
        if (is_null($logger)) {
            $logger = Log::factory('null');
        }
        $this->_logger = $logger;
        return true;
    }
    
    /**
     * 返回之前设置的日志对象
     */
    public function getLogger()
    {
        return $this->_logger;
    }
    
    /**
     * 记录日志，如果设置过日志对象 ，将调用日志对象的log方法，否则抛出异常
     * @param string $message
     * @param int $priority
     * @return void
     */
    public function log($message, $priority = OpModel::LOG_ERR)
    {
        if (is_null($this->_logger)) {
            if ($priority <= OpModel::LOG_ERR) {
                throw new Exception("[$priority] $message");
            }
        } else {
            $this->_logger->log($message, $priority);
        }
    }
    
    /**
     * 设置错误号和错误信息，用于某些需要返回具体错误原因的接口
     * @param int $errno
     * @param string $error
     * @return boolean
     */
    protected function _setError($errno, $error = '')
    {
        $this->_errno = $errno;
        $this->_error = $error;
        return true;
    }
    
    /**
     * 获取错误号
     */
    public function getErrorNo()
    {
        return $this->_errno;
    }
    
    /**
     * 获取错误信息
     */
    public function getErrorMessage()
    {
        return $this->_error;
    }
}